//
//  YTableView.swift
//  NewNGPlay
//
//  Created by YMac on 2017/12/14.
//  Copyright © 2017年 zchd. All rights reserved.
//
open class YAdapter<T:NSObject,J:UITableViewCell>: UIResponder,YBaseAdapter,UIScrollViewDelegate {
    private var tableView:UITableView!
    
    private var yDataSource = [T]()
    private var onInitCell:((T,IndexPath) -> (J))?
    private var onYBuild:((J,T,IndexPath) -> ())?
    private var onHeightForRow:((T,IndexPath) -> (CGFloat))?
    private var onDidSelectRow:((T,IndexPath) -> ())?
    private var onScrollToBottom:(() -> ())?
    private var onHeightForHeaderInSection:((Int) -> (CGFloat))?
    private var onViewForHeaderInSection:((Int) -> (UIView?))?
    private var onHeightForFooterInSection:((Int) -> (CGFloat))?
    private var onViewForFooterInSection:((Int) -> (UIView?))?
    
    public override init() {
        super.init()
    }
    
    public init(_ dataSource:[T],onBuild onYBuild: ((J,T,IndexPath) -> ())?) {
        self.yDataSource = dataSource
        self.onYBuild = onYBuild
    }
    
    public func reloadData(dataSource:[T]){
        self.yDataSource = dataSource
        tableView.reloadData()
    }
    
    public func setOnInitCell(_ doSomeThing:@escaping (T,IndexPath) -> (J)) -> YAdapter{
        self.onInitCell = doSomeThing
        return self
    }
    
    public func setOnScrollToBottom(_ doSomeThing:@escaping () -> ()) -> YAdapter{
        self.onScrollToBottom = doSomeThing
        return self
    }
    
    public func setOnHeightForRow(_ doSomeThing:@escaping (T,IndexPath) -> (CGFloat)) -> YAdapter{
        self.onHeightForRow = doSomeThing
        return self
    }
    
    public func setDidSelectRow(_ doSomeThing:@escaping (T,IndexPath) -> ()) -> YAdapter{
        self.onDidSelectRow = doSomeThing
        return self
    }
    
    public func setOnHeightForHeaderInSection(_ doSomeThing:@escaping (Int) -> (CGFloat)) -> YAdapter{
        self.onHeightForHeaderInSection = doSomeThing
        return self
    }
    
    public func setOnViewForHeaderInSection(_ doSomeThing:@escaping (Int) -> (UIView?)) -> YAdapter{
        self.onViewForHeaderInSection = doSomeThing
        return self
    }
    
    public func setOnHeightForFooterInSection(_ doSomeThing:@escaping (Int) -> (CGFloat)) -> YAdapter{
        self.onHeightForFooterInSection = doSomeThing
        return self
    }
    
    public func setOnViewForFooterInSection(_ doSomeThing:@escaping (Int) -> (UIView?)) -> YAdapter{
        self.onViewForFooterInSection = doSomeThing
        return self
    }
    
    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if onHeightForRow != nil {
            return onHeightForRow!(self.yDataSource[indexPath.row], indexPath)
        }else{
            return 50
        }
    }
    
    public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        if onHeightForHeaderInSection != nil {
            return onHeightForHeaderInSection!(section)
        }else{
            return 0
        }
    }
    
    public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if onViewForHeaderInSection != nil {
            return onViewForHeaderInSection!(section)
        }else{
            return nil
        }
    }
    
    public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        if onHeightForFooterInSection != nil {
            return onHeightForFooterInSection!(section)
        }else{
            return 0
        }
    }
    
    public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        if onViewForFooterInSection != nil {
            return onViewForFooterInSection!(section)
        }else{
            return nil
        }
    }
    
    public final func numberOfSections(in tableView: UITableView) -> Int {
        self.tableView = tableView
        return 1
    }
    
    public final func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.yDataSource.count
    }
    
    public final func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell:J?
        if onInitCell != nil {
            cell = onInitCell?(self.yDataSource[indexPath.row],indexPath)
        } else {
            cell = tableView.dequeueReusableCell(withIdentifier: "\(type(of: J(frame: .zero)))") as? J
            if cell == nil {
                cell = J(style: .default, reuseIdentifier: "\(type(of: J(frame: .zero)))")
            }
        }
        onYBuild!(cell!, self.yDataSource[indexPath.row],indexPath)
        return cell!
    }
    
    public final func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        onDidSelectRow?(self.yDataSource[indexPath.row], indexPath)
    }
    
    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        let y = scrollView.contentSize.height - scrollView.contentOffset.y
        if yDataSource .count > 0 && y < scrollView.contentSize.height && y < scrollView.frame.height{
            onScrollToBottom?()
        }
    }
}
